home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-05 / driverss.zip / NTI16.ASM < prev    next >
Assembly Source File  |  1991-02-08  |  31KB  |  1,298 lines

  1. version    equ    0
  2.  
  3.     include    defs.asm
  4. ;        ntinet.mac
  5. ;
  6. ;  macros used for calling c routines.
  7. ;
  8. pusharg    macro    seg, off
  9.     ifnb    <seg>
  10.       push    seg
  11.     $$cnt = $$cnt+2
  12.     endif
  13.     ifnb    <off>
  14.       push    off
  15.     $$cnt = $$cnt+2
  16.     endif
  17.     endm
  18.  
  19.  
  20. ccall    macro    rtn, p1, p2, p3, p4, p5
  21. $$cnt = 0
  22.     ifnb    <p5>
  23.       pusharg    p5
  24.     endif
  25.     ifnb    <p4>
  26.       pusharg    p4
  27.     endif
  28.     ifnb    <p3>
  29.       pusharg    p3
  30.     endif
  31.     ifnb    <p2>
  32.       pusharg    p2
  33.     endif
  34.     ifnb    <p1>
  35.       pusharg    p1
  36.     endif
  37.       call    rtn
  38.     if $$cnt
  39.       add    sp,$$cnt
  40.     endif
  41.     endm
  42.  
  43. save    macro    regs
  44.       irp    arg,<regs>
  45.       push    arg
  46.       endm
  47.     endm
  48.     
  49. restore    macro    regs
  50.       irp    arg,<regs>
  51.       pop    arg
  52.       endm
  53.     endm
  54.  
  55. ;
  56.  
  57.     include    lance.inc
  58.  
  59. ;
  60. ;  GLBL.INC
  61. ;
  62. ;  global equates for lance dumb board
  63. ;
  64. pt_status    equ    0        ;read status port
  65. pt_clrclk    equ    0        ;write to clear clock interrupt
  66. pt_etaddr    equ    1        ;read ether address rom offset
  67. pt_resetl    equ    1        ;write to reset lance
  68. pt_ldata    equ    2        ;lance data port 2,3
  69. pt_laddr    equ    4        ;lance address port 4,5
  70.  
  71. st_mask        equ    0ch        ;00001100B for (is1 is0)
  72.  
  73. ;int selects
  74. irqn_10    equ    00h            ;(is0 is1) = (0 0)
  75. irqn_11    equ    04h            ;(0 1)
  76. irqn_12    equ    08h            ;(1 0)
  77. irqn_15    equ    0ch            ;(1 1)
  78.  
  79. IRQ10        equ    10
  80.  
  81. ; status port bits
  82.  
  83. NET_INT    equ    01h        ;bit for net interrupt status
  84. CLK_INT    equ    02h        ;bit for clock interrupt status
  85. IPL    equ    04h        ;ipl bit
  86. HILO    equ    08h        ;ram at 0000, or ram at 8000
  87. MINT    equ    net_int+clk_int        ;interrupt mask
  88. ADDR    equ    0F0h        ;mask for dual port segment
  89.  
  90.  
  91. DPLEN    equ    8000h        ;length of dual port ram
  92. BUFSIZE equ    1518        ;should change to GIANT + 4(CRC)
  93.  
  94. ; Packet sizes = source(6) + destination(6) + type (2) + I field. (803.2 spec)
  95. ;
  96.  
  97. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  98. ;
  99. ;Following is the list of variables that need to be adjusted if the dp
  100. ;usage is changed:
  101. ;
  102. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  103.  
  104. XAREA        equ    5F78H        ;start of transmit descriptors
  105. RAREA        equ    0018h        ;start of receive descriptors
  106.  
  107. NUMTDESC    equ    4        ;number of transmit descriptors
  108. NUMRDESC    equ    16         ;number of receive descriptors
  109.  
  110. TBAREA    equ    XAREA+(NUMTDESC*tdesclen)    ;xmit buf pool
  111. RBAREA    equ    RAREA+(NUMRDESC*rdesclen)       ;rcv buffer pool
  112.  
  113. ;our data segment is a constant distance from the es!
  114. OUROFFSET    equ    TBAREA + NUMTDESC*BUFSIZE
  115.  
  116. RLEN    equ    RLEN16            ;lance mask for rcv-descriptors
  117. TLEN    equ    TLEN4            ;lance mask for snd-descriptors
  118.  
  119. ;the total dp size reserved for lance use
  120. LANCE_SZ equ    INITBLK_SZ+ NUMRDESC*(RDESCLEN+BUFSIZE)+ NUMTDESC*(TDESCLEN+BUFSIZE)
  121.  
  122. ;the end of RAERA
  123. OUTOF_BOUND    equ     RBAREA        ;98; for wrap up checking of r-descs
  124.  
  125.  
  126. code    segment    word public
  127.     assume    cs:code, ds:code
  128.  
  129.     extrn    maskint:near
  130.     extrn    set_recv_isr: near
  131.  
  132.  
  133.     public    int_no, io_addr, base_addr
  134. int_no        db    3,0,0,0        ; interrupt number. 
  135. io_addr        dw    0338h,0        ; I/O address for card (jumpers)
  136. base_addr    dw      0d000h,0    ; base segment for board (jumper set)
  137.  
  138. int_no_name    db    "Interrupt number ",'$'
  139. io_addr_name    db    "I/O port ",'$'
  140. base_addr_name    db    "Memory address ",'$'
  141.  
  142. nosdesc_msg    db    "no send descriptor.",CR,LF,'$'
  143. chperr_msg    db    "chip doesn't want to finish init",CR,LF,'$'
  144. porterr_msg    db    "wrong port #",CR,LF,'$'
  145. hwerr_msg    db    "hardware error",CR,LF,'$'
  146. initerr_msg    db     "can't init lance chip",CR,LF,'$'
  147. good_msg    db    "Lance initialized successfully.",CR,LF,'$'
  148. reset_msg    db    "Can't reset the interface",CR,LF,'$'
  149. interr_msg    db    "IRQ# parameter wrong.",CR,LF,'$'
  150.  
  151.     public    driver_class, driver_type, driver_name, driver_function, parameter_list
  152. driver_class    db    BLUEBOOK, IEEE8023, 0        ;from the packet spec
  153. driver_type    db    100        ;--mz?
  154. driver_name    db    'nti',0,'$'    ;name of the driver.
  155. driver_function    db    2
  156. parameter_list    label    byte
  157.     db    1    ;major rev of packet driver
  158.     db    9    ;minor rev of packet driver
  159.     db    14    ;length of parameter list
  160.     db    EADDR_LEN    ;length of MAC-layer address
  161.     dw    GIANT    ;MTU, including MAC headers
  162.     dw    MAX_MULTICAST * EADDR_LEN    ;buffer size of multicast addrs
  163.     dw    0    ;(# of back-to-back MTU rcvs) - 1
  164.     dw    0    ;(# of successive xmits) - 1
  165. int_num    dw    0    ;Interrupt # to hook for post-EOI
  166.             ;processing, 0 == none,
  167.  
  168.     public    rcv_modes
  169. rcv_modes    dw    4        ;number of receive modes in our table.
  170.         dw    0,0,0,rcv_mode_3
  171.  
  172.  
  173.     ;begin importing data
  174.     public    UNITID, sdesc_cnt, rdesc_cnt, actsdesc, actrdesc
  175. UNITID    db    6 dup (0)        ;current ether address of the interface
  176. sdesc_cnt    dw    2        ;
  177. rdesc_cnt    dw    8
  178. actsdesc    dw    0
  179. actrdesc    dw    0
  180.  
  181.  
  182.  
  183. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  184. ; send_pkt:
  185. ;
  186. ;enter with ds:si -> packet, cx = packet length.
  187. ;exit with nc if ok, or else cy if error, dh set to error number.
  188. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  189.  
  190.     public    as_send_pkt
  191. ; The Asynchronous Transmit Packet routine.
  192. ; Enter with es:di -> i/o control block, ds:si -> packet, cx = packet length,
  193. ;   interrupts possibly enabled.
  194. ; Exit with nc if ok, or else cy if error, dh set to error number.
  195. ;   es:di and interrupt enable flag preserved on exit.
  196. as_send_pkt:
  197.     ret
  198.  
  199.     public    drop_pkt
  200. ; Drop a packet from the queue.
  201. ; Enter with es:di -> iocb.
  202. drop_pkt:
  203.     assume    ds:nothing
  204.     ret
  205.  
  206.     public    xmit
  207. ; Process a transmit interrupt with the least possible latency to achieve
  208. ;   back-to-back packet transmissions.
  209. ; May only use ax and dx.
  210. xmit:
  211.     assume    ds:nothing
  212.     ret
  213.  
  214.  
  215.     public    send_pkt
  216. send_pkt:
  217.     assume    ds:nothing
  218.     push    es
  219.     call    set_dp
  220.  
  221.     push    ds
  222.     call    set_ds            ;set out ds-->cs
  223.  
  224.     mov    dx,cx            ;a copy of length
  225.  
  226.     cmp    dx,GIANT        ; Is this packet too large?
  227.     ja    send_pkt_toobig
  228.  
  229.     cmp    dx,RUNT            ; minimum length for Ether
  230.     jnb    oklen
  231.     mov    dx,RUNT            ; make sure size at least RUNT
  232. oklen:
  233.     mov    bx,[actsdesc]        ;get pointer to active snd desc
  234.     mov    cx,0            ;set up count down parameters
  235. td10:
  236.     test    es:td_stat[bx],t_own    ;have empty buffer?
  237.     jz    dox0            ;yes, then send message
  238.     loop    td10            ;otherwise, wait for it
  239.     mov    dx,offset nosdesc_msg
  240.     ccall    _dispMSG,dx
  241.     mov    dh,CANT_SEND
  242.     stc                ;error ret
  243.     pop    ds
  244.     pop    es
  245.     ret
  246.  
  247. dox0:
  248.     pop    ds
  249.     mov    cx,dx            ;get back the real length
  250.     call    fill            ;ds:si - source, es:bx - dest, cx:length
  251.     ;ax has the return code, either 0 or 0ffh
  252.  
  253.     ;is chip functioning?
  254.     cmp    ax,0ffh            ;fatal error happened last time?
  255.     je    td15            ;error!
  256.     clc                ;good ret
  257.     pop es
  258.     ret
  259. td15:
  260.     mov    dh,CANT_SEND
  261.     stc
  262.     pop    es
  263.     ret
  264.  
  265. send_pkt_toobig:
  266.     mov    dh,NO_SPACE
  267.     stc
  268.     pop    ds
  269.     pop    es
  270.     ret
  271.  
  272.     include    movemem.asm
  273.  
  274. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  275. ; fill - proc the xerror  & copy message to xmit buffer
  276. ;
  277. ; entry - es:bx points to free xmit descriptor (dest)
  278. ;      ds:si --> source buf pointer
  279. ;        cx:length of data
  280. ;
  281. ; exit  - xmit buffer (bx) filled
  282. ;      ax = 0: OK; 0ffh: fatal error happened last send
  283. ;      bx changed
  284. ;
  285. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  286.     public    fill
  287. fill:
  288.     assume    ds:nothing
  289.     push    ds                ;save theirs
  290.  
  291.     call    set_ds                ;set ours
  292.  
  293.     call    xmt_errs            ;process previous errors
  294.     cmp    ax,0
  295.     je    success
  296.     pop    ds
  297.     ret                    ;ax == ffh
  298.  
  299. success:    
  300.     ;ds:si - source, es:bx - dest, cx - length
  301.     ;simply send whatever given by the application, assuming the
  302.     ;destination address and everything has been taken care of
  303.  
  304.     pop    ds
  305.     push    cx            ;save it
  306.     mov    di,es:td_addr[bx]    ;get dest buf pointer 
  307.     call    movemem            ;ds:si --> es:di
  308.     pop    cx
  309.     
  310.     push    ds
  311.     call    set_ds
  312.     ;get the sdesc ready and pump the data out
  313.     neg    cx            ;two's compliment
  314.     or    cx,td_bmask        ;set these bits
  315.     mov    es:td_bcnt[bx],cx    ;set in length to descriptor
  316.     mov    ax,0            ;set descriptor status for lance
  317.     or    ax,t_own        ;he now owns it
  318.     or    ax,t_stp        ;start of packet
  319.     or    ax,t_enp        ;end of packet
  320.     mov    es:td_stat[bx],ax    ;give it away        
  321.     mov    ax,l_tdnd+l_inea    ;tell lance we have data
  322.     call    w_csr                ;send it
  323.  
  324.     ;all done, update the actsdesc
  325.     add    bx,tdesclen        ;point at next descriptor
  326.     dec    word ptr[sdesc_cnt]        ;dec counter
  327.     jnz    tfl                ;used all?
  328.     mov    word ptr[sdesc_cnt],NUMTDESC    ;yes start at begining    
  329.     mov    bx,XAREA
  330. tfl:
  331.     mov    [actsdesc],bx        ;set pointer
  332.  
  333.     mov    ax,0            
  334.     pop    ds
  335.     ret                ;good ret
  336.  
  337. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  338. ; xmt_errs:
  339. ;    Check at if the previous send has any errors or not.
  340. ;     entry - es:bx sdesc
  341. ;    exit  - ax:0 - ok; ffh:fatal error
  342. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  343.  
  344.     public    xmt_errs
  345. xmt_errs:
  346.     mov    ax,es:td_tdr[bx]    ;get rest of status
  347.     test    ax,t_more        ;more than one retry needed
  348.     jz    xisr2
  349.     call    count_out_err
  350.     jmp    xisr3
  351. xisr2:
  352.     test    ax,t_one        ;one retry?
  353.     jz    xisr3            ;no
  354.     call    count_out_err
  355. xisr3:
  356.     test    ax,t_lcol        ;late collision
  357.     jz    xisr4            ;no
  358.     call    count_out_err
  359. xisr4:
  360.     test    ax,t_def        ;deferred xmit?
  361.     jz    xisr5
  362.     call    count_out_err
  363. xisr5:
  364.     test    ax,t_lcar        ;loss of carrier
  365.     jz    xisr6
  366.     call    count_out_err
  367. xisr6:
  368.     test    ax,t_uflo        ;silo underflow?
  369.     jz    xisr7    
  370.     jmp    fatal_err
  371. xisr7:    
  372.     test    ax,t_buff        ;buffer error no end
  373.     jz    all_rite        ;last sent all right
  374. fatal_err:
  375.     call    count_out_err
  376.     mov    ax,0ffh            ;fatal error
  377.     ret                ;
  378.  
  379. all_rite:
  380.     mov    ax,0
  381.     ret
  382.  
  383. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  384. ;get_address:
  385. ;    We get the interface address from our internal version UNITID. 
  386. ;    set_address() could change the value of UNITID.
  387. ;
  388. ;enter with es:di -> place to put the address, cx = size of address buffer.
  389. ;exit with nc, cx = actual size of address, or cy if buffer not big enough.
  390. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  391.  
  392.     public    get_address
  393. get_address:
  394.     assume    ds:code
  395.     cmp    cx,EADDR_LEN        ;make sure that we have enough room.
  396.     jb    get_address_2
  397.     mov    cx,EADDR_LEN
  398.     lea    si,UNITID
  399. get_address_1:
  400.     call    movemem
  401.     mov    cx,EADDR_LEN
  402.     clc
  403.     ret
  404. get_address_2:
  405.     stc
  406.     ret
  407.     
  408. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  409. ; set_address:
  410. ;    set current ethernet address in UNITID, also change the init block
  411. ;       
  412. ;enter with ds:si -> Ethernet address, CX = length of address.
  413. ;exit with nc if okay, or cy, dh=error if any errors.
  414. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  415.  
  416.     public    set_address
  417. set_address:
  418.     assume    ds:nothing
  419.     push     ax
  420.     push    di
  421.     push    es
  422.     mov    ax,cs
  423.     mov    es,ax
  424.     
  425.     cmp    cx,EADDR_LEN
  426.     jne    set_address2
  427.  
  428.     push    si                ;save it for later use
  429.     push    cx
  430.  
  431.     mov    di,offset UNITID
  432.     call    movemem
  433.  
  434.     ;should also change the init_block
  435.     call    set_dp
  436.     mov    di,offset i_padr            
  437.     pop    cx
  438.     pop    si                ;get back the old pointer
  439.     call    movemem
  440.  
  441.     pop    es
  442.     pop    di
  443.     pop    ax
  444.     clc
  445.     ret
  446.  
  447. set_address2:
  448.     mov    dh,BAD_ADDRESS
  449.     stc
  450.     pop    es
  451.     pop    di
  452.     pop    ax
  453.     ret
  454.  
  455.  
  456.  
  457. rcv_mode_3:
  458. ;receive mode 3 is the only one we support, so we don't have to do anything.
  459.     ret
  460.  
  461.  
  462.     public    set_multicast_list
  463. set_multicast_list:
  464. ;enter with ds:si ->list of multicast addresses, cx = number of addresses.
  465. ;return nc if we set all of them, or cy,dh=error if we didn't.
  466.     mov    dh,NO_MULTICAST
  467.     stc
  468.     ret
  469.  
  470.  
  471.     public    terminate
  472. terminate:
  473.     ret
  474.  
  475.     public    reset_interface
  476. reset_interface:
  477. ;reset the interface.
  478.     assume    ds:code
  479.     call    hardware        ;reset the UNITID
  480.     cmp    al,0
  481.     jne    port_err
  482.  
  483.     cli
  484.  
  485.     call    lance_init        ;init_blk, xmt, rcv
  486.     cmp    ax,0            ;init ok?
  487.     jne    lance_err
  488.     sti
  489.     clc
  490.     ret
  491.  
  492. lance_err:
  493.     mov    dx,offset initerr_msg
  494.     ccall    _dispMSG,dx
  495.     jmp    error
  496.  
  497. port_err:    
  498.     mov    dx,offset reset_msg
  499.     ccall    _dispMSG,dx
  500. error:
  501.     mov    dh,CANT_RESET
  502.     stc
  503.     ret
  504.  
  505. ;called when we want to determine what to do with a received packet.
  506. ;enter with cx = packet length, es:di -> packet type, dl = packet class.
  507.     extrn    recv_find: near
  508.  
  509. ;called after we have copied the packet into the buffer.
  510. ;enter with ds:si ->the packet, cx = length of the packet.
  511.     extrn    recv_copy: near
  512.  
  513.     extrn    count_in_err: near
  514.     extrn    count_out_err: near
  515.  
  516. ;called from the net_isr isr.  All registers have been saved, and ds=cs.
  517. ;Upon exit, the interrupt will be acknowledged.
  518. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  519. ; risr 
  520. ; receive interrupt service routine 
  521. ; exit: es,bx not changed
  522. ; registers: si,ax
  523. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  524.  
  525.     public    risr
  526. risr    proc    near
  527.     assume    ds:code
  528.     save    <es,bx>
  529.     call    set_dp            ;set es to dual port
  530. begin:
  531.     mov    si,[actrdesc]        ;active receive descriptor
  532.     mov    ax,es:rd_stat[si]    ;get descriptor status
  533.     test    ax,r_own        ;do we own it?
  534.     jnz    risr_done        ;this one is not filled
  535.  
  536.     call    dp_rcv            ;lance chip has rev'd a new packet
  537.                     ;reserve si 
  538.     ;One rint might indicate multiple recv's, check at the next one
  539.     add    si,SIZE rec_desc_ring        ;point at next descriptor
  540.     cmp    si,OUTOF_BOUND            ;RAREA+(numrxbuf-1)*(SIZE rec_desc_ring) = XAREA
  541.     jl    within
  542.     mov    si,RAREA
  543. within:
  544.     mov    [actrdesc],si            ;set active pointer
  545.     jmp    begin
  546. risr_done:
  547.     restore <bx,es>
  548.     ret
  549. risr    endp
  550.  
  551. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  552. ;  dp_rcv:
  553. ;    lance chip has one buffer filled, process it.
  554. ;    enter: es:si = actrdesc
  555. ;    exit:  actrdesc updated to next desc, si unchanged
  556. ;    registers: di,ax,bx
  557. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  558.  
  559.     public    dp_rcv
  560. dp_rcv     proc     near
  561.     push    si                ;save the old actdesc
  562.     push    es            ;gonna be changed in recv_find()
  563.  
  564.     mov    ax,es:rd_stat[si]    ;is it errored packet?
  565.     test    ax,r_err        ;
  566.     jz    noerr                 ;no err
  567.     call     rcverror        ;handle the err 
  568.     jmp    clrup
  569.  
  570. noerr:
  571.     mov     di,es:rd_addr[si]    ;received packet pointer es:di
  572.     add    di,EADDR_LEN + EADDR_LEN;stript off the two ether addresses
  573.                     ; & get to the packet type field
  574.     mov    cx,es:rd_mcnt[si]    ;everything (icl'g addresses)
  575.     and    cx,mcnt_mask        ;mask out the reserved bits
  576.  
  577.     push    ds            ;entry value saved
  578.  
  579.     push    es            ;es:di --> rcv'd data (icl'ing type)
  580.     push    di
  581.  
  582.     mov    dl, BLUEBOOK        ;assume bluebook Ethernet.
  583.     mov    ax, es:[di]
  584.     xchg    ah, al
  585.     cmp     ax, 1500
  586.     ja    BlueBookPacket
  587.     inc    di            ;set di to 802.2 header
  588.     inc    di
  589.     mov    dl, IEEE8023
  590. BlueBookPacket:
  591.  
  592.     call    recv_find        ;ask for buffer from application es:di
  593.     mov    ax,es            ;is this pointer null?
  594.     or    ax,di
  595.     jz    too_bad            ;yes - just free the frame.
  596.     pop    si            ;put rcv'd data in ds:si, di->si
  597.     sub    si,EADDR_LEN + EADDR_LEN;we hand everything to the client
  598.     pop    ds            ;es->ds
  599.  
  600.     push    cx
  601.     push    es            ;for recv_copy(), es:di is user buf
  602.     push    di            
  603.  
  604.     call    movemem            ;do the copy (including ether header)
  605.  
  606.     pop    si            ;di->si, es->ds
  607.     pop    ds            ;ds:si --> user buffer now
  608.     pop    cx            ;get back the length
  609.     call    recv_copy
  610.  
  611.     pop    ds            ;original ds restored
  612.     jmp    clrup
  613.  
  614. too_bad:
  615.     pop    di
  616.     pop    es
  617.     pop    ds
  618. clrup:
  619.     ;either a bad or a good packet, we're done with it now
  620.     pop    es            ;good old dp seg
  621.     pop    si
  622.     mov    es:rd_stat[si],r_own    ;desc reusable now
  623.     ret
  624. dp_rcv    endp
  625.  
  626. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  627. ; eisr
  628. ; for lance error service routine
  629. ;
  630. ; entry - bx has status
  631. ; exit  - bx unchanged, ax,cx changed
  632. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  633.  
  634.     public    eisr
  635. eisr    proc    near
  636.     test    bx,l_babl        ;transmission timeout?
  637.     jz    eisr1            ;no
  638.     call    count_out_err
  639. eisr1:
  640.     test    bx,l_cerr    
  641.     jz    eisr2            ;no
  642.     call    count_out_err
  643. eisr2:
  644.     test    bx,l_miss        ;missed packet?
  645.     jz    eisr3
  646.     call    count_out_err
  647. eisr3:
  648.     test    bx,l_merr        ;bus timeout?
  649.     jz    eisr4            ;no
  650.     call    count_out_err        ;this is a fatal error
  651. eisr4:
  652.     ret
  653. eisr    endp
  654.  
  655. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  656. ; rcverror:
  657. ;    entry    ax has rd_stat
  658. ;
  659. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  660.  
  661.     public    rcverror
  662. rcverror    proc    near
  663.  
  664.     test    ax,r_fram        ;framing error?
  665.     jz    rerr0
  666.     call     count_in_err
  667. rerr0:
  668.     test    ax,r_crc        ;crc error?
  669.     jz    rerr1
  670.     call     count_in_err
  671. rerr1:
  672.     test    ax,r_oflo          ;silo overflow?
  673.     jz    rerr2
  674.     call     count_in_err
  675. rerr2:
  676.     test    ax,r_buff        ;buffer error?
  677.     jz    rerr3
  678.     call     count_in_err
  679. rerr3:
  680.     ret
  681. rcverror    endp
  682.  
  683. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  684. ; init_csr:
  685. ;
  686. ; initialize lance registers csr1, csr2, csr3
  687. ;  entry - csr0 stop bit must have been set
  688. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  689.  
  690.     public    init_csr
  691. init_csr    proc    near
  692.     mov    al,csr1            ;set rap to csr1
  693.     call    set_rap
  694.     mov    ax,i_mode        ;init block starts at 0
  695.     call    w_csr
  696.  
  697.     mov    al,csr2            ;set rap to csr2
  698.     call    set_rap
  699.     mov    ax,0            ;init block upper 8 bits are 0
  700.     call    w_csr
  701.  
  702.     mov    al,csr3            ;set rap for csr3
  703.     call    set_rap
  704.     mov    ax,bus_master        ;bswp,acon,bcon
  705.     call    w_csr
  706.  
  707.     mov    al,csr0            ;leave rap at csr0
  708.     call    set_rap
  709.     ret
  710. init_csr    endp    
  711.  
  712. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  713. ; r_csr:
  714. ;
  715. ; read lance csr already selected into ax
  716. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  717.  
  718.     public    r_csr
  719. r_csr    proc    near
  720.     push    dx
  721.     mov    dx,io_addr        ;now data port
  722.     add    dx,pt_ldata
  723.     in    ax,dx
  724.     pop    dx
  725.     ret
  726. r_csr    endp
  727. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  728. ; r_csr0
  729. ;
  730. ; read lance csr0
  731. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  732.  
  733.     public    r_csr0
  734. r_csr0    proc    near
  735.     push    dx
  736.     mov    al,csr0            ;set rap to csr1
  737.     call    set_rap
  738.     mov    dx,io_addr        ;now data port
  739.     add    dx,pt_ldata
  740.     in    ax,dx
  741.     pop    dx
  742.     ret
  743. r_csr0    endp
  744.  
  745. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  746. ; set_initblk:  
  747. ;
  748. ; set up lance initialization block in the dual port  
  749. ;
  750. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;                       ;
  751.  
  752.     public    set_initblk,si11
  753. set_initblk  proc    near
  754.     push    es
  755.     call    set_dp            ;get lance data seg
  756.  
  757.     mov    ax,run_mode        ;mode
  758.     mov    es:[i_mode],ax        ;(es = dpseg);1st word in the dp
  759.     lea    si,UNITID        ;set in physical address
  760.     mov    di,i_padr        ; from the board
  761. si11:
  762.     mov    cx,6
  763.     rep    movsb
  764. ;
  765. ;forget about the logical address filter for now --mz??
  766. ;
  767.     mov    ax,RAREA        ;set in pointer to 1ST receive desc.
  768.     mov    es:[i_rdra],ax        ;set lo addr (0-15)
  769.     mov    ah,rlen            ;set in rlen parameter & hi addr (00s)
  770.     mov    al,0
  771.     mov    es:[i_rlen],ax        ;4 rcv descriptors
  772.     mov    ax,XAREA        ;pointer to xmit descriptors
  773.     mov    es:[i_tdra],ax
  774.     mov    ah,tlen            ;set in tlen parameter 1 = 2
  775.     mov    al,0
  776.     mov     es:[i_tlen],ax
  777.     pop    es
  778.     ret
  779. set_initblk    endp
  780.  
  781. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  782. ; set_dp
  783. ;    es<-- cs:base_address
  784. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  785.  
  786.     public    set_dp
  787. set_dp:
  788.     assume    cs:code
  789.     push    ax
  790.     mov    ax,cs:[base_addr]
  791.     mov    es,ax
  792.     pop    ax
  793.     ret
  794.  
  795. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  796. ; set_ds:
  797. ;     ds<--cs
  798. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  799. set_ds:
  800.     push    ax
  801.     mov    ax,cs
  802.     mov    ds,ax
  803.     pop    ax
  804.     ret
  805.  
  806. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  807. ; set up transmit message descriptors
  808. ;
  809. ; entry - cx has number of descriptors and buffers to set up
  810. ;         bx has pointer of start of descriptors
  811. ;         di has pointer to start of buffer area
  812. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  813.  
  814.     public    su_tmd
  815. su_tmd    proc    near
  816.     push    es
  817.     call    set_dp            ;get lance data seg
  818.  
  819.     ;first set the relative parameters
  820.     mov    [sdesc_cnt],cx        ;set in count
  821.     mov    [actsdesc],bx
  822.  
  823. su_t0:
  824.     mov    es:td_addr[bx],di    ;set in pointer
  825.     mov    ax,BUFSIZE        ;total size
  826.     neg    ax            ;two's compliment
  827.     or    ax,td_bmask        ;set these bits
  828.     mov    es:td_bcnt[bx],ax    ;set in length to descriptor
  829.     mov    ax,0            ;set descriptor status for lance
  830.     or    ax,t_stp        ;start of packet
  831.     or    ax,t_enp        ;end of packet
  832.     mov    es:td_stat[bx],ax    ;give it away        
  833.     mov    es:td_tdr[bx],0
  834.     add    bx,tdesclen        ;point at next descriptor
  835.     add    di,BUFSIZE        ;and next buffer
  836.     loop    su_t0            ;do all
  837.     pop    es
  838.     ret
  839. su_tmd    endp
  840.  
  841. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  842. ; set up receive message descriptors
  843. ;
  844. ; entry - cx has number of descriptors and buffers to set up
  845. ;         bx has pointer of start of descriptors
  846. ;         di has pointer to start of buffer area
  847. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  848.  
  849.     public    su_rmd
  850. su_rmd    proc    near
  851.     push    es
  852.     call    set_dp    ;get lance data seg
  853.  
  854.     mov    [actrdesc],bx          ;pointer to active descriptor
  855.     mov    [rdesc_cnt],cx        ;descriptor count
  856. su_r0:
  857.     mov    es:rd_addr[bx],di       ;set in pointer to pointer
  858.     mov    ax,r_own        ;set up descriptor status 
  859.     mov    es:rd_stat[bx],ax
  860.     xor    ax,ax            ;zero out count
  861.     mov    es:rd_mcnt[bx],ax
  862.     mov    ax,BUFSIZE        ;set in length of buffer
  863.     neg    ax            ;must be two's compliment
  864.     or    ax,rd_mask        ;need these bits set
  865.     mov    es:rd_bcnt[bx],ax
  866.     add    bx,rdesclen        ;point at next descriptor
  867.     add    di,BUFSIZE        ;and next buffer
  868.     loop    su_r0            ;do all
  869.     
  870.     pop    es
  871.     ret
  872. su_rmd    endp
  873.  
  874. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  875. ; lance_reset:
  876. ;
  877. ;     reset lance chip; select csr0 and set the stop bit
  878. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;        
  879.  
  880.     public    lance_reset
  881. lance_reset    proc    near
  882.     mov    dx,io_addr        ;pop the reset line
  883.     add    dx,pt_resetl    
  884.     out    dx,al
  885.     mov    al,csr0            ;set lance address port to csr0
  886.     call    set_rap
  887.     mov    ax,l_stop         ;and set stop bit
  888.     call    w_csr
  889.     ret
  890. lance_reset    endp
  891.  
  892. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  893. ; w_csr:
  894. ;
  895. ; output ax to lance csr already selected
  896. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  897.  
  898.     public    w_csr
  899. w_csr    proc    near
  900.     push    dx
  901.     mov    dx,io_addr        ;now data port
  902.     add    dx,pt_ldata
  903.     out    dx,ax
  904.     pop    dx
  905.     ret    
  906. w_csr    endp
  907.  
  908. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  909. ; set_rap:
  910. ;
  911. ; set lance address port to register in al
  912. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  913.  
  914.     public    set_rap
  915. set_rap    proc    near
  916.     push    dx
  917.     mov    dx,io_addr        ;get base address
  918.     add    dx,pt_laddr                ;point at lance address port
  919.     xor    ah,ah            ;point at csr
  920.     out    dx,ax
  921.     pop    dx
  922.     ret
  923. set_rap        endp
  924.  
  925. ; hardwre() and lance_init() are TSR just for the 
  926. ; support of reset_interface();
  927.  
  928. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  929. ; hardware: 
  930. ;    verify the port #;
  931. ;    set ethernet addr in _UNITID
  932. ;
  933. ; exit:
  934. ;    [_UNITID] = board ethernet address
  935. ;       al = 0 (ok)
  936. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  937.  
  938.     public    hardware
  939. hardware    proc    near
  940.     ;verify the port #
  941.     mov    dx,io_addr
  942.     call    chkaddr
  943.     cmp    al,0            ;ok?
  944.     jz    hw1            ;yes, use #1
  945.     mov    ax,offset porterr_msg
  946.     ccall    _dispMSG,ax
  947.     jmp    hw_error
  948.  
  949. hw1:
  950.     ;ok, now zero the ram out so that we can use it
  951.     call    set_dp
  952.     call     zeroram
  953.  
  954.     ;get ether address
  955.     mov    cx,6            ;get the ethernet address
  956.     add    dx,pt_etaddr
  957.     mov    bx,offset UNITID    ;to here
  958. hw3:
  959.     in    al,dx
  960.     mov    byte ptr[bx],al
  961.     inc    bx
  962.     loop    hw3
  963.  
  964.     ;validate int_no (only support 10,11,12,15)
  965.     
  966.     mov    bl,IRQ10        ;assume it's irq10
  967.     mov    dx,io_addr        ;port base
  968.     add     dx,pt_status        ;status port
  969.     in    al,dx            ;get status
  970.     and    al,st_mask        ;get the 2 bits
  971.     cmp    al,irqn_10        ;(IS0 IS1)=(0 0) selects irq10
  972.     je    alset
  973.     inc    bl            ;try irq11
  974.     cmp    al,irqn_11
  975.     je    alset
  976.     inc    bl            ;try irq12
  977.     cmp    al,irqn_12
  978.     je    alset
  979.     mov    bl,15            ;try irq15
  980.     cmp    al,irqn_15
  981.     jne    hw_error
  982.  
  983. alset:
  984.     ;did we get the right int_no in bl?
  985.     cmp    bl,int_no
  986.         jmp     ok                      ; #### temp patch, BKC
  987. ;    je    ok
  988.     ;otherwise, error
  989.     mov    ax,offset interr_msg
  990.     ccall    _dispMSG,ax
  991. hw_error:
  992.     mov    al,0ffh
  993.     ret
  994. ok:
  995.     mov    al,0            ;good return code
  996.     ret
  997. hardware    endp
  998.  
  999. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1000. ; chkaddr: check if we are using the right i/o port
  1001. ;          this is done by reading the port status and comparing
  1002. ;       with cs - 800h
  1003. ;
  1004. ; entry:     io_addr == i/o port #
  1005. ; exit:     ah -- dual port segment
  1006. ;        al -- 00h (succ) or ffh (error)
  1007. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1008.  
  1009.     public    chkaddr
  1010. chkaddr    proc    near
  1011.     push    dx
  1012.  
  1013.     mov    dx,io_addr
  1014.     in    al,dx            ;read in status byte
  1015.     and    al,addr            ;get dp seg, addr = 0f0h
  1016.     mov    ah,al            ;save
  1017.  
  1018.     mov    dx,base_addr
  1019.     and    dh,addr
  1020.     cmp    al,dh
  1021.     je    chk2
  1022.     mov    al,0ffh            ;error
  1023.     pop    dx
  1024.     ret
  1025. chk2:
  1026.     mov    al,0            ;ok
  1027.     pop    dx
  1028.     ret
  1029. chkaddr    endp
  1030.  
  1031. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1032. ; zeroram - zero dual port ram
  1033. ;    seg in [dpseg]
  1034. ;    registers: di,cx,al
  1035. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1036.  
  1037.     public    zeroram
  1038. zeroram    proc    near
  1039.     cld                ;auto increment
  1040. zram1:    
  1041.     mov    di,0            ;start at 0;dpseg:di
  1042.     mov    cx,dplen        ;dual port length
  1043.     mov    al,0            ;data to go
  1044.     rep    stosb            ;zero em all
  1045.     ret
  1046. zeroram    endp
  1047.  
  1048. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1049. ; lance_init:
  1050. ;
  1051. ; init lance chip; first setup init_blk, r & s descriptors in dp
  1052. ;           then set the chip to go.
  1053. ;    exit: ax = 1: error; 0 OK. 
  1054. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1055.  
  1056.     public    lance_init, il0, il1
  1057. lance_init    proc    near
  1058.     call    set_initblk        ;set up lance initialization block
  1059.  
  1060.     ;set up transmit descriptors & buffers
  1061.     mov    cx,NUMTDESC        ;get no. of transmit blocks to build
  1062.     mov    bx,XAREA        ;point at descriptor memory pool
  1063.     mov    di,TBAREA        ;and buffer pool
  1064.     call    su_tmd            ;set up transmit descriptors
  1065.  
  1066.     ;set up receive descriptors & buffers
  1067.     mov    cx,NUMRDESC        ;set up receive descriptors
  1068.     mov    bx,RAREA        ;descriptor area
  1069.     mov    di,RBAREA        ;buffer area
  1070.     call    su_rmd            ;set up receive descriptors
  1071.  
  1072.     call    lance_reset        ;ensure reset
  1073.     call    init_csr        ;initialize lance registers
  1074.                     ;also set rap to csr0 with stop set
  1075.     ;now start the lance initialization action
  1076.     CLI
  1077.     mov    ax,l_init+l_strt    ;write init & start to csr0
  1078.     call    w_csr
  1079.  
  1080.     ;rap = csr0 now, let's check at csr0
  1081.        mov    cx,0
  1082.     dec    cx
  1083. il0:
  1084.     call    r_csr            ;get lance status register
  1085.     test    ax,l_idon        ;init done set?
  1086.     jnz    il1
  1087.     loop    il0
  1088.     ;sth wrong with the chip, can't init
  1089.     mov    ax,offset chperr_msg
  1090.     ccall    _dispMSG,ax
  1091.     mov    ax,1            ;error return
  1092.     ret
  1093. il1:
  1094.     mov    ax,l_idon+l_inea    ;this drives /intr pin to low
  1095.     call    w_csr            ;enable network ints
  1096.     STI
  1097.     mov    ax,0            ;good return
  1098.     ret
  1099. lance_init    endp
  1100.  
  1101. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1102. ;  tickscreen
  1103. ;
  1104. ;  For debug this routine can be called to tick over the screen at the 
  1105. ;  specified location.
  1106. ;
  1107. ;    c callable:    tickscreen(loc);
  1108. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1109.  
  1110.     public    _tickscreen
  1111. _tickscreen    proc near
  1112.     push    bp
  1113.     mov    bp,sp
  1114.     save    <ax,bx,ds>
  1115.     mov    bx,04[bp]        ;get screen position
  1116.     add    bx,bx            ;*2
  1117. IFDEF COLOR
  1118.     mov    ax,0b800h
  1119. ELSE
  1120.     mov    ax,0b000h
  1121. ENDIF
  1122.     mov    ds,ax
  1123.     inc    byte ptr [bx]            ;tick it
  1124.     restore    <ds,bx,ax>
  1125.     pop    bp
  1126.     ret
  1127. _tickscreen    endp
  1128.  
  1129. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1130. ; _dispMSG:
  1131. ;    c call: dispMSG(&msg);
  1132. ;    put the '$' terminated message to screen
  1133. ;    entry: dx - point to the message
  1134. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1135.  
  1136.     public    _dispMSG
  1137. _dispMSG proc near
  1138.     push    bp
  1139.     mov    bp,sp
  1140.     push    dx
  1141.     mov    dx,4[bp]
  1142.  
  1143.     push    ax
  1144.     mov    ah,9
  1145.     int    21h
  1146.     pop    ax
  1147.  
  1148.     pop    dx
  1149.     pop    bp
  1150.     ret
  1151. _dispMSG endp
  1152.  
  1153.  
  1154.     public    recv
  1155. recv:
  1156. ;called from the recv isr.  All registers have been saved, and ds=cs.
  1157. ;Upon exit, the interrupt will be acknowledged.
  1158.     assume    ds:code
  1159.  
  1160. recv_0:
  1161.     mov    dx,io_addr        ;get the iobase
  1162.     add    dx,pt_status        ;the read status port
  1163.     in    al,dx            ;get board status
  1164.  
  1165.     test    al,clk_int        ;look for clock interrupt
  1166.     jz    ni10            ;no clock int
  1167.     mov    dx,base_addr
  1168.     add    dx,pt_clrclk        ;reset the ckock
  1169.     out     dx,al
  1170. ni10:
  1171.     test    al,net_int        ;network int bit cleared?
  1172.     jnz    nisr5            ;look for 0 here, set means none
  1173.  
  1174.     call    r_csr            ;get lance status register -- in ax
  1175.     mov    bx,ax
  1176.     and    ax,l_mask         ;clear out ints and mask any more
  1177.     call    w_csr
  1178.  
  1179.     test    bx,l_err        ;check for errors first
  1180.     jz    nisr2            ;no error
  1181.     call    eisr
  1182. nisr2:
  1183.     test    bx,l_rint        ;test for receive active
  1184.     jz    nisr6            ;no r_int
  1185.     call    risr
  1186. nisr6:
  1187.     mov     ax,l_inea        ;re-enable the int
  1188.     call    w_csr
  1189.     jmp    recv_0            ;check again for ints
  1190. nisr5:
  1191.     ret
  1192.  
  1193.  
  1194.     public    recv_exiting
  1195. recv_exiting:
  1196. ;called from the recv isr after interrupts have been acknowledged.
  1197. ;Only ds and ax have been saved.
  1198.     assume    ds:nothing
  1199.     ret
  1200.  
  1201.  
  1202. ;any code after this will not be kept after initialization.
  1203. end_resident    label    byte
  1204.  
  1205.  
  1206.     public    usage_msg
  1207. usage_msg    db    "usage: nti16 [-n] [-d] [-w] <packet_int_no> <irq_no> <port_no> <base_addr>",CR,LF,'$'
  1208.  
  1209.     public    copyright_msg
  1210. copyright_msg    db    "Packet driver for nti network device, version ",'0'+majver,".",'0'+version,CR,LF
  1211.         db    "Copyright 1990, Michael Zheng",CR,LF,'$'
  1212.  
  1213.  
  1214. ;enter with si -> argument string, di -> wword to store.
  1215. ;if there is no number, don't change the number.
  1216.     extrn    get_number: near
  1217.  
  1218. ;enter with dx -> name of word, di -> dword to print.
  1219.     extrn    print_number: near
  1220.  
  1221.     public    parse_args
  1222. parse_args:
  1223.     mov    di,offset int_no
  1224.     call    get_number
  1225.     mov    di,offset io_addr
  1226.     call    get_number
  1227.     mov    di,offset base_addr
  1228.     call    get_number
  1229.     ret
  1230.  
  1231. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1232. ; etopen:
  1233. ;    initialize the interface in order to function
  1234. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1235.  
  1236.     public    etopen
  1237. etopen:
  1238.  
  1239.  
  1240.     call     hardware        ;decide port #; _UNITID; zeroram
  1241.                     ;and 16-bit board specific:
  1242.                     ;decide the int_no validity --mz!!
  1243.     cmp    al,0
  1244.     jz    beg0            ;ok
  1245.     mov    ax,offset hwerr_msg    ;error return
  1246.     ccall    _dispMSG,ax
  1247.     mov    ax, 4c00H
  1248.     int    21h            ;terminate it
  1249. beg0:
  1250.  
  1251.     mov    al,int_no
  1252.     call    maskint
  1253.     call    lance_init        ;init the lance chip
  1254.     cmp    ax,1            ;init error?
  1255.     jne    good            ;ok
  1256.  
  1257.     mov    ax,offset initerr_msg    ;can't init message
  1258.     ccall    _dispMSG,ax
  1259.     stc    
  1260.     ret
  1261.  
  1262. good:
  1263.     call    set_recv_isr
  1264.  
  1265.     mov    al, int_no        ; Get board's interrupt vector
  1266.     add    al, 8
  1267.     cmp    al, 8+8            ; Is it a slave 8259 interrupt?
  1268.     jb    set_int_num        ; No.
  1269.     add    al, 70h - 8 - 8        ; Map it to the real interrupt.
  1270. set_int_num:
  1271.     xor    ah, ah            ; Clear high byte
  1272.     mov    int_num, ax        ; Set parameter_list int num.
  1273.  
  1274.     mov    ax,offset good_msg
  1275.     ccall    _dispMSG,ax
  1276.  
  1277.     mov    dx,offset end_resident    ;in paragraphs
  1278.     clc
  1279.     ret
  1280.  
  1281.     public    print_parameters
  1282. print_parameters:
  1283. ;echo our command-line parameters
  1284.     mov    di,offset int_no
  1285.     mov    bx,offset int_no_name
  1286.     call    get_number
  1287.     mov    di,offset io_addr
  1288.     mov    bx,offset io_addr_name
  1289.     call    get_number
  1290.     mov    di,offset base_addr
  1291.     mov    bx,offset base_addr_name
  1292.     call    get_number
  1293.     ret
  1294.  
  1295. code    ends
  1296.  
  1297.     end
  1298.